#include"zookeeperutil.h"
#include"RpcApplication.h"
#include<semaphore.h>
#include<iostream>

void global_watcher(zhandle_t *zh,int type,int state,const char * path,void * wacherCtx)
{
    if(type == ZOO_SESSION_EVENT)
    {
        if(state == ZOO_CONNECTED_STATE)
        {
            sem_t * sem = (sem_t*)zoo_get_context(zh);
            sem_post(sem);
        }
    }
}
ZKClient::ZKClient(): m_zhandle(nullptr)
{

}
ZKClient::~ZKClient()
{
    if(m_zhandle != nullptr)
    {
        zookeeper_close(m_zhandle);
    }
}
void ZKClient::Start()
{
    std::string host = RpcApplication::getInstance().getInstanceConfig().Load("zookeeperip");
    std::string port = RpcApplication::getInstance().getInstanceConfig().Load("zookeeperport");
    std::string connstr = host+":"+port;

    m_zhandle = zookeeper_init(connstr.c_str(),global_watcher,3000,nullptr,nullptr,0);
    if(m_zhandle == nullptr)
    {
        std::cout<<"zookeeper_init error!"<<std::endl;
        exit(-1);
    } 

    sem_t sem;
    sem_init(&sem,0,0);
    zoo_set_context(m_zhandle,&sem);

    sem_wait(&sem);
    std::cout<<"zookeeper_init success!"<<std::endl;
}
void ZKClient::Create(const char * path,const char *data,int datalen,int state)
{
    char pathBuffer[128];
    int bufferLen = sizeof(pathBuffer);
    int flag;
    flag = zoo_exists(m_zhandle,path,0,nullptr);
    if(ZNONODE == flag)
    {
            flag = zoo_create(m_zhandle,path,data,datalen,
            &ZOO_OPEN_ACL_UNSAFE,state,pathBuffer,bufferLen);
            if(flag == ZOK)
            {
                std::cout<<"znode create success path:"<<path<<std::endl;
            }else
            {
                std::cout<<"flag:"<<flag<<std::endl;
                std::cout<<"znode create error path : "<<path<<std::endl;
                exit(-1);
            }
    }
}
std::string ZKClient::GetData(const char * path)
{
    char buff[64];
    int buffLen = sizeof(buffer);
    int flag = zoo_get(m_zhandle,path,0,buff,&buffLen,nullptr);
    if(flag != ZOK)
    {
        std::cout<<"get znode error path:"<<path<<std::endl;
        return "";
    }else
    {
        return buff;
    }
}